﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using Photon;
using PlayFab;
using PlayFab.ClientModels;
using UnityEngine.SceneManagement;

public class LoginManager : Photon.MonoBehaviour 
{	
	public static LoginManager instance;

	public static LoginManager Instance
	{
		get{return instance;}
		set{instance = value;}
	}
	#region Vars
	public GameObject[] menu = new GameObject[2];


	public InputField loginUserField;
	public InputField loginPassField;

	public InputField regUserField;
	public InputField regPassField;
	public InputField regConfField;

	public InputField regEmailField;

	public InputField lobbyAddFriendField;

	public GameObject regUserToggle;
	private trueFalseUI regUserTFUI;

	public GameObject regPassToggle;
	private trueFalseUI regPassTFUI;

	public GameObject regConfPassToggle;
	private trueFalseUI regConfPassTFUI;

	public GameObject loginUserToggle;
	private trueFalseUI loginUserTFUI;

	public GameObject loginPassToggle;
	private trueFalseUI loginPassTFUI;

	public GameObject lobbyAddFriendToggle;
	private trueFalseUI lobbyAddFriendTFUI;

	public Text welcometext;
	public Text networkStatusText;
	private RoomOptions options;

	public GameObject friendViewContent;
	public GameObject friendViewPrefab;
	public Button playButton;

	public PhotonNetworkManager photonManager;
	public Text maxPlayersFieldText;
	#endregion

	#region Auto Functions
	void Awake()
	{	
		if (instance != this)
			instance = this;
		regUserTFUI = regUserToggle.GetComponent<trueFalseUI> ();
		regPassTFUI = regPassToggle.GetComponent<trueFalseUI> ();
		regConfPassTFUI = regConfPassToggle.GetComponent<trueFalseUI> ();
		loginUserTFUI = loginUserToggle.GetComponent<trueFalseUI> ();
		loginPassTFUI = loginPassToggle.GetComponent<trueFalseUI> ();
		lobbyAddFriendTFUI = lobbyAddFriendToggle.GetComponent<trueFalseUI> ();
		foreach (GameObject thisMenu in menu)
		{
			thisMenu.SetActive (false);
		}
		playButton.interactable = false;
		OpenMenu (0);
		welcometext.gameObject.SetActive (false);
		DontDestroyOnLoad (this);
	}
	void Update () 
	{	
		if (networkStatusText != null)
		networkStatusText.text = PhotonNetwork.connectionStateDetailed.ToString ();
	}
	#endregion



	#region Photon
	public void Connect ()
	{		
		options = new RoomOptions()
		{
			MaxPlayers = 4,
			PublishUserId = true,
		};

		if (PhotonNetwork.connectionStateDetailed.ToString () != "JoinedLobby")
		{
			PhotonNetwork.ConnectUsingSettings (GameConstants.Version);
		}

	}

	public virtual void OnJoinedLobby()
	{
		Debug.Log ("you have joined a Lobby");
		PhotonNetwork.player.UserId = AccountInfo.instance.Info.AccountInfo.Username;
		playButton.interactable = true;
	}
	public void JoinBestRoom()
	{	
		int mostPlayers = 0;
		string bestRoomName;
		bestRoomName = null;
		foreach (RoomInfo room in PhotonNetwork.GetRoomList())
		{
			if ((room.PlayerCount > mostPlayers) && (room.PlayerCount < room.MaxPlayers))
			{
				mostPlayers = room.PlayerCount;
				bestRoomName = room.Name;

			}

		}
		Debug.Log (bestRoomName);
		if (bestRoomName != null)
		{
			PhotonNetwork.JoinRoom (bestRoomName);

		} else
		{
			PhotonNetwork.CreateRoom ("", options, null);
		}


	}
	public virtual void OnJoinedRoom()
	{	
		//if (PhotonNetwork.playerList.Length == PhotonNetwork.room.MaxPlayers )
		{
		}
	}



	public void OnPhotonSerializeView()
	{
	}
	#endregion

	//code from old lobby scene

	// end code from old lobby scene

	#region Login
	public void SoftLogin()
	{	
		bool invalidPass = (loginPassField.text == null || loginPassField.text == "" || loginPassField.text.Length < 6 || loginPassField.text.Length > 100);
		bool invalidUser = (loginUserField.text == null || loginUserField.text == "" || loginUserField.text.Length < 3 || loginUserField.text.Length > 20);

		if (invalidUser)
		{	
			loginUserTFUI.False ();
			loginPassToggle.SetActive (false);
			return;
		}
		if (invalidPass)
		{	
			loginPassToggle.SetActive (false);
			loginUserToggle.SetActive (false);
			string password = GameFunctions.RandomString (16);
			LoginWithPlayFabRequest request = new LoginWithPlayFabRequest () {
				Username = loginUserField.text,
				Password = password,
			};

			PlayFabClientAPI.LoginWithPlayFab (request, OnCheckUserStub, OnLoginCheckUser);
			return;
		}

		loginPassToggle.SetActive (false);
		loginUserToggle.SetActive (false);
		Login (loginUserField.text,loginPassField.text);

	}
	public void Login(string username, string password)
	{
		LoginWithPlayFabRequest request = new LoginWithPlayFabRequest() 
		{
			Username = username,
			Password = password,
		};
		PlayFabClientAPI.LoginWithPlayFab (request, OnLogin, LoginError);
	}

	 void OnLogin(LoginResult result)
	{	
		GetAccountInfo (result.PlayFabId);
		OpenMenu (2);
		Debug.Log ("Logged in with: " + result.PlayFabId);


	}
	 void GetAccountInfo(string playFabId)
	{
		GetPlayerCombinedInfoRequestParams paramInfo = new GetPlayerCombinedInfoRequestParams ()
		{
			GetTitleData = true,
			GetUserInventory = true,
			GetUserAccountInfo = true,
			GetUserVirtualCurrency = true,
			GetPlayerProfile = true,
			GetPlayerStatistics = true,
			GetUserData = true,
			GetUserReadOnlyData = true,

		};
		GetPlayerCombinedInfoRequest request = new GetPlayerCombinedInfoRequest()
		{
			PlayFabId = playFabId,
			InfoRequestParameters = paramInfo, 

		};
		PlayFabClientAPI.GetPlayerCombinedInfo (request, OnGetAccountInfo, GameFunctions.OnAPIError);

		GetFriendList ();
	}
	void GetFriendList ()
	{
		GetFriendsListRequest request = new GetFriendsListRequest ();
		PlayFabClientAPI.GetFriendsList (request, OnGetFriends, GameFunctions.OnAPIError);

	}
	void OnGetAccountInfo(GetPlayerCombinedInfoResult result)
	{
		Debug.Log ("Updated account info");
		AccountInfo.instance.Info = result.InfoResultPayload;
		Connect ();
	}
	void OnGetFriends(GetFriendsListResult result)
	{	
		Debug.Log ("Got friends list");
		AccountInfo.instance.FriendList = result.Friends;
		MakeFriendMenu ();
	}


	void OnLoginCheckUser(PlayFabError error)
	{	
		string errorString = error.ToString ();
		if (errorString.Contains ("AccountNotFound"))
		{	

			loginUserTFUI.False ();
			loginPassToggle.SetActive (false);
		} else
		{	

			loginUserTFUI.True ();
			loginPassTFUI.False ();
		}
		
	}

	void LoginError(PlayFabError error)
	{	
		string errorString = error.ToString ();
		Debug.Log (errorString);
		if (errorString.Contains ("AccountNotFound"))
		{
			loginUserTFUI.False ();
		} else
		{
			loginUserTFUI.True ();
		}
		if (errorString.Contains ("InvalidUsernameOrPassword"))
		{
			loginPassTFUI.False ();
		} 


	}

	public void FastLogin()
	{
		Login("nigel65","nigel65");
	}


	#endregion

	#region Register
	public void Register()
	{
		RegisterPlayFabUserRequest request = new RegisterPlayFabUserRequest () 
		{	
			RequireBothUsernameAndEmail = false,
			TitleId = PlayFabSettings.TitleId,
			Username = regUserField.text,
			DisplayName = regUserField.text,
			Password = regPassField.text,


		};
		PlayFabClientAPI.RegisterPlayFabUser (request, OnRegister, RegisterError);
	}
	public void SoftRegister()
	{	
		bool invalidUser = (regUserField.text == null || regUserField.text == "" || regUserField.text.Length < 3 || regUserField.text.Length > 20);

		CheckPassword ();
		ConfirmPassword ();
		regConfPassToggle.SetActive (true);
		if (invalidUser)
		{
			regUserTFUI.False ();
		}
		if (!invalidUser)
		{
			if (regConfPassTFUI.isTrue && regPassTFUI.isTrue)
			{
				Register ();
			} else
				CheckUser ();
			CheckPassword ();
			ConfirmPassword ();

		}
	}
	void OnRegister(RegisterPlayFabUserResult result)
	{	
		OpenMenu (2);
		Debug.Log ("Registered with: " + result.PlayFabId);
		GetAccountInfo (result.PlayFabId);
	}
	void RegisterError(PlayFabError error)
	{
		string errorString = error.ToString ();
		if (errorString.Contains ("UsernameNotAvailable") || errorString.Contains ("NameNotAvailable"))
		{
			regUserTFUI.False ();
		} else
		{
			regUserTFUI.True ();
		}
	}
	public void CheckUser()
	{	
		regUserToggle.SetActive (false);
		regPassToggle.SetActive (false);
		regConfPassToggle.SetActive (false);
		
		string username = regUserField.text;
		string password = GameFunctions.RandomString (16);
		LoginWithPlayFabRequest request = new LoginWithPlayFabRequest () {
			Username = username,
			Password = password,
		};

		PlayFabClientAPI.LoginWithPlayFab (request, OnCheckUserStub, OnCheckUser);


	}
	 void OnCheckUserStub(LoginResult result)
	{
		//this method is a placeholder and should never be called
	}
	 void OnCheckUser(PlayFabError error)
	{	
		string errorString = error.ToString ();
		if (errorString.Contains ("AccountNotFound"))
		{	

			regUserTFUI.True ();
		} else
		{	

			regUserTFUI.False ();
		}
			
	}
	public void CheckPassword()
	{
		string password = regPassField.text;
		if (password.Length < 6)
		{	
			regPassTFUI.False ();
			return;
		} 
		if (password.Length > 100)
		{
			regPassTFUI.False ();
			return;
		}
		regPassTFUI.True ();
	}
	public void ConfirmPassword()
	{
		string actualPass = regPassField.text;
		string confPass = regConfField.text;
		if (confPass != "")
		{
			if (confPass != actualPass)
			{
				regConfPassTFUI.False ();
			} else
			{
				regConfPassTFUI.True ();
			}
		} else
		{
			regConfPassTFUI.False ();
			regConfPassToggle.SetActive (false);
		}

			
	}
	#endregion

	#region Lobby

	public void PopUpMenu(GameObject popUp)
	{
		popUp.SetActive (!popUp.activeSelf);
	}

	public void AddFriend()
	{	
		lobbyAddFriendToggle.SetActive (false);
		AddFriendRequest request = new AddFriendRequest () {
			FriendUsername = lobbyAddFriendField.text,
		};
		PlayFabClientAPI.AddFriend (request,OnAddFriend,OnAddFriendError);
	}
	void OnAddFriend(AddFriendResult result)
	{	
		Debug.Log("added friend");
		GetFriendList ();
		lobbyAddFriendField.text = null;
	}
	void OnAddFriendError(PlayFabError error)
	{	
		Debug.Log (error);
		if (error.ToString ().Contains ("UsersAlreadyFriends"))
		{
			lobbyAddFriendTFUI.True ();
			return;
		} else
		{
			lobbyAddFriendTFUI.False ();
		}
	}
	void MakeFriendMenu()
	{	
		foreach (Transform child in friendViewContent.transform)
		{
			GameObject.Destroy (child.gameObject);
		}
		int i = 1;
		RectTransform rectTransform = friendViewContent.GetComponent<RectTransform> ();
		rectTransform.sizeDelta = new Vector2( rectTransform.sizeDelta.x, 40F * AccountInfo.instance.FriendList.Count);
		foreach(PlayFab.ClientModels.FriendInfo friend in AccountInfo.instance.FriendList)
		{
			GameObject obj = Instantiate (friendViewPrefab, friendViewContent.transform);
			RectTransform rect = obj.GetComponent<RectTransform> ();
			Text text = obj.GetComponentInChildren<Text> ();
			//Button button = obj.GetComponentInChildren<Button> ();
			//button.onClick.AddListener(() => RemoveFriendButton(text));
			text.text = friend.Username;
			rect.localPosition = new Vector2 (rect.localPosition.x,i * -40F + 10F);
			i++;
		}
	}

	public void RemoveFriendButton(Text friendNameText)
	{	
		foreach (PlayFab.ClientModels.FriendInfo friend in AccountInfo.instance.FriendList)
		{	Debug.Log (friend.Username);
			if (friend.Username == friendNameText.text)
			{	
				Debug.Log ("there is a match");
				RemoveFriend (friend);
				return;
			}
		}
	}
	void RemoveFriend(PlayFab.ClientModels.FriendInfo friend)
	{	
		Debug.Log (friend.FriendPlayFabId);
		RemoveFriendRequest request = new RemoveFriendRequest ()
		{
			FriendPlayFabId = friend.FriendPlayFabId,
		};
		PlayFabClientAPI.RemoveFriend (request, OnRemoveFriend, GameFunctions.OnAPIError);

	}
	void OnRemoveFriend(RemoveFriendResult result)
	{	
		GetFriendList ();
		MakeFriendMenu ();
	}
	void OnRemoveFrinedError(PlayFabError error)
	{
		Debug.Log (error);


	}


	public void LogOut()
	{	
		Debug.Log("Logged out");
		AccountInfo.instance.Info.AccountInfo = null;
		OpenMenu (0);
	}

	public void FindMatch()
	{	
		playButton.interactable = false;
		JoinBestRoom ();
	}


	#endregion

	public void OpenMenu(int index)
	{
		GameFunctions.OpenMenu (menu, index);
	
	}


		
}
